package com.hhck.service.impl;

import com.hhck.entity.ProductType;
import com.hhck.entity.Result;
import com.hhck.mapper.ProductMapper;
import com.hhck.mapper.ProductTypeMapper;
import com.hhck.service.ProductTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@CacheConfig(cacheNames = "com.hhck.service.impl.ProductTypeServiceImpl")
@Service
public class ProductTypeServiceImpl implements ProductTypeService {

    @Autowired
    private ProductTypeMapper productTypeMapper;

    @Autowired
    private ProductMapper productMapper;

    /**
     * 查询所有商品类型
     */
    @Cacheable(key = "'all:productType'")
    @Override
    public List<ProductType> queryAllProductType() {

        // 查询所有商品类型
        List<ProductType> productTypeList = productTypeMapper.selectAllProductType();

        // 将商品类型集合转换为商品类型树
        List<ProductType> productTypeTree = productTypeListToTree(productTypeList, 0);

        return productTypeTree;
    }

    /**
     * 将商品类型集合转换为商品类型树
     */
    private List<ProductType> productTypeListToTree(List<ProductType> productTypeList, Integer parentId) {

        // 创建商品类型树
        List<ProductType> productTypeTree = new ArrayList<>();

        // 遍历商品类型集合
        for (ProductType productType : productTypeList) {
            // 先将所有一级分类（父id为0的商品类型）放入商品类型树
            if (productType.getParentId().equals(parentId)) {
                productTypeTree.add(productType);
            }
        }

        // 遍历商品类型树
        for (ProductType productType : productTypeTree) {
            // 递归此方法，从商品类型集合中找出父id与当前一级分类id一致的二级分类
            List<ProductType> childProductTypeList = productTypeListToTree(productTypeList, productType.getTypeId());
            // 为一级分类划分二级分类
            productType.setChildProductCategory(childProductTypeList);
        }

        return productTypeTree;
    }

    /**
     * 校验分类编码是否存在
     */
    @Override
    public Result queryProductByTypeCode(ProductType productType) {

        ProductType isExistProductType = productTypeMapper.selectProductByTypeCodeOrTypeName(productType);

        // 这里前端只接收true或者false，返回true表示不存在，返回false表示存在
        return Result.ok(isExistProductType == null);
    }

    /**
     * 添加商品分类（注意清理缓存）
     */
    @CacheEvict(key = "'all:productType'")
    @Override
    public Result saveProductType(ProductType productType) {

        // 校验商品名称是否重复
        ProductType isExistTypeName = productTypeMapper.selectProductByTypeCodeOrTypeName(productType);
        if (isExistTypeName != null) {
            return Result.err(Result.CODE_ERR_BUSINESS, "商品名称已存在！");
        }

        // 添加商品分类
        int num = productTypeMapper.insertProductType(productType);
        if (num == 1) {
            return Result.ok("添加成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "添加失败！");
    }

    /**
     * 删除商品分类及其子类（注意清理缓存）
     */
    @CacheEvict(key = "'all:productType'")
    @Override
    public Result removeProductTypeAndChildType(Integer typeId) {

        // 根据要删除类型的id查询其以及其所有子类的id
        List<Integer> allTypeId = getAllTypeId(typeId);

        // 新建一个集合用来存放查询出的所有类型id
        List<Integer> typeIdList = new ArrayList<>();
        // 注意：要转移数据，将查询出的数据全部添加到新建的集合当中
        // 因为 allTypeId 和 parentTypeAndChildTypeIdList 指向同一个内存地址，如果不转移数据的话，在清空集合的时候数据会丢失
        typeIdList.addAll(allTypeId);

        // 注意：一定要清空这个集合（这是用来存放查询出类型id的集合，是个成员变量），否则下次使用时会产生重复数据
        parentTypeAndChildTypeIdList.clear();

        // 遍历父类及其所有子类id的集合
        for (Integer id : typeIdList) {
            // 查询当前类型下是否有商品
            int productCount = productMapper.selectProductCountByTypeId(id);
            // 如果有商品则无法删除这个分类
            if (productCount > 0) {
                return Result.err(Result.CODE_ERR_BUSINESS, "分类下还有商品，无法删除！");
            }
        }
        // 程序执行到这里，说明要删除的这个类型以及它所有的子类下没有商品了，可以删除这些分类

        // 根据分类id集合删除分类
        int num = productTypeMapper.deleteProductTypeByTypeIdList(typeIdList);
        if (num == typeIdList.size()) {
            return Result.ok("删除成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "删除失败！");
    }

    /**
     * 修改商品分类（注意清理缓存）
     */
    @CacheEvict(key = "'all:productType'")
    @Override
    public Result modifyProductTypeByTypeId(ProductType productType) {

        // 首先判断分类名称是否存在，根据分类名称查询分类对象
        ProductType isExistTypeName = productTypeMapper.selectProductByTypeCodeOrTypeName(productType);
        // 如果查询结果为空，表示不存在，可以修改
        // 如果查询结果不为空，同时查询出分类的id和要修改分类的id不一致，表示存在，不可以修改
        if (isExistTypeName != null &&  ! isExistTypeName.getTypeId().equals(productType.getTypeId())) {
            return Result.err(Result.CODE_ERR_BUSINESS, "分类名称已存在！");
        }

        int num = productTypeMapper.updateProductTypeByTypeId(productType);
        if (num == 1) {
            return Result.ok("修改成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "修改失败！");
    }

    /**
     * 根据商品分类id查询出其下所有子类的id（返回结果为该类的id和它所有子类的id）
     */
    private List<Integer> parentTypeAndChildTypeIdList = new ArrayList<>();
    private List<Integer> getAllTypeId(Integer typeId) {

        // 将要查询的分类id放入分类id集合中
        parentTypeAndChildTypeIdList.add(typeId);

        // 根据父id（当前typeId）查询出直属子类的id
        List<Integer> chileTypeIdList = productTypeMapper.selectChildTypeIdListByParentId(typeId);

        // 判断子类id集合是否为空
        if (!chileTypeIdList.isEmpty()) {
            // 不为空，遍历子类id集合
            for (Integer chileTypeId : chileTypeIdList) {
                // 递归此方法，根据当前子类id，查询出该子类下的直属子类id
                getAllTypeId(chileTypeId);
            }
        }

        // 直到当前类下没有子类，返回存有要查询的分类及其所有子类id的集合
        return parentTypeAndChildTypeIdList;
    }

}

